#ifndef PHYSICS_H
#define PHYSICS_H

#include <GameGlobals.h>
#include <DebugDraw.h>

#include <vector>
#include <map>

class BaseObject;

class PhysicsManager
{
	struct CollisionPair
	{
		CollisionPair(BaseObject* a = 0, BaseObject* b = 0):first(a),second(b){}
		BaseObject* first;
		BaseObject* second;
	};

	class CollisionListener : public b2ContactListener
	{
		std::vector< CollisionPair >* collisionPairs;
		public:
			void Init(std::vector< CollisionPair >* _collisionPairs) {
				collisionPairs = _collisionPairs;
			}

			// Called when two fixtures begin to touch
			virtual void BeginContact(b2Contact* contact) {
			  BaseObject* a = 0; BaseObject* b = 0;
			  void* bodyUserData = contact->GetFixtureA()->GetBody()->GetUserData();
			  if ( bodyUserData )
				a = static_cast<BaseObject*>( bodyUserData );
			  else
			    return;
		  
			  bodyUserData = contact->GetFixtureB()->GetBody()->GetUserData();
			  if ( bodyUserData )
				b = static_cast<BaseObject*>( bodyUserData );
			  else
				return;

			  collisionPairs->push_back( CollisionPair(a,b) );		  
			}
	};

	public:

		PhysicsManager();
		~PhysicsManager();

		void Init();
		void Update(float dt = 0.016f);
		void Cleanup();
		void SetPause(truth state);
		void SetCollisions(truth state);
		void SetDebugMode(truth state);
		void DoOneStep();
		std::vector<vec2> LoadBoundingBox(std::string filename);

		void DoDebugDraw();

	public:

		truth debugDrawEnabled;
		DebugDraw debugDraw;
		b2World* world;
		CollisionListener collisionListener;
	
	private:
				
		truth AddBoundingBox( std::vector<vec2>& points, std::string filename );
		truth HasBoundingBox( std::string filename );
		void ProcessCollisions();
		std::vector< std::vector<vec2> > boundingBoxes;
		std::map<std::string, unsigned > loadedBBs;
		std::vector< CollisionPair > collisionPairs;
		truth paused;
		truth oneStep;
		truth collisions;
		truth debugMode;
};



#endif